/*
 * Copyright (C) 2011 Mette Bank, Rikke Jensen, Kenneth Brodersen, Thomas Pedersen
 * 
 * This file is part of digiPECS.
 * 
 * digiPECS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * digiPECS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with digiPECS.  If not, see <http://www.gnu.org/licenses/>.
 */

package sw6.digipecs.widget.user;

import sw6.digipecs.exceptions.ImageIsEmptyException;
import sw6.digipecs.exceptions.NoViewFoundException;
import sw6.digipecs.model.PECSBook;
import sw6.digipecs.widget.AnimationLayout;
import sw6.digipecs.widget.BitmapImageView;
import sw6.digipecs.widget.DragableExtImageView;
import sw6.digipecs.widget.ExtImageAdapter;
import sw6.digipecs.widget.ExtImageGridView;
import sw6.digipecs.widget.PageBarLayout;
import sw6.digipecs.widget.dragdrop.DragLayout;
import sw6.digipecs.widget.dragdrop.DragSource;
import sw6.digipecs.widget.dragdrop.DropTarget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;

public class PECSBookPageView extends ExtImageGridView implements DragSource, DropTarget {
	
	private PECSBook mBook;
	private Context mContext;
	private final Rect mRect = new Rect();
	private AnimationLayout mAnimationLayout;
	private PageBarLayout mPageBar;

	public PECSBookPageView(Context context) {
		super(context);
		
		mContext = context;
	}

	public PECSBookPageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		mContext = context;
	}

	public PECSBookPageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		
		mContext = context;
	}
	
	public void setUp(PECSBook book, DragLayout dragLayout, PageBarLayout pageBar) {
		final ExtImageAdapter adapter = new ExtImageAdapter(mContext, book.getCurrentPage(), new ExtImageAdapter.DraggableExtImageViewFactory(dragLayout, book, pageBar));
		book.addOnChangeListener(adapter);
		setAdapter(adapter);
		
		mBook = book;
		mPageBar = pageBar;
	}
	
	public void setAnimationLayer(AnimationLayout al) {
		mAnimationLayout = al;
	}

	@Override
	public void onSuccessfulDrop(View v, DropTarget target) {
		final Rect rect = mRect;
		getHitRect(rect);
		
		if (target instanceof SentenceBoardLayout) {
			TranslateAnimation animation = new TranslateAnimation(-getWidth(), 0, 0, 0);
			animation.setDuration(250);
			v.startAnimation(animation);
		}
	}

	@Override
	public boolean drop(View fromView, int x, int y) {
		// If no animation layout has been set, then we do not do anything
		//TODO Shouldn't they be moved anyways ? (just without animation) 
		if (mAnimationLayout == null) return false;
		
		// Do the drop
		try {
			View toView = findView(x, y);
			
			if (toView instanceof ViewGroup) {
				toView = ((ViewGroup) toView).getChildAt(0);
			}
			
			// If dropped on itself do nothing
			if (fromView == toView) return false;
			
			if (fromView instanceof DragableExtImageView && toView instanceof DragableExtImageView) {
				final DragableExtImageView fromExt = (DragableExtImageView) fromView;
				final DragableExtImageView toExt = (DragableExtImageView) toView;
				
				// Make sure the drag came from within the book
				if (fromExt.getPageDraggedFrom() == -1) return false;
				
				// Create bitmaps for animation
				fromExt.buildDrawingCache();
				final Bitmap fromBitmap = Bitmap.createBitmap(fromExt.getDrawingCache());
				final BitmapImageView fromBiv = new BitmapImageView(mContext, fromBitmap);
				toExt.buildDrawingCache();
				final Bitmap toBitmap = Bitmap.createBitmap(toExt.getDrawingCache());
				final BitmapImageView toBiv = new BitmapImageView(mContext, toBitmap);
				
				// Create listener
				AnimationListener al = new AnimationListener() {
					private boolean mStopable = true;
					@Override
					public void onAnimationStart(Animation animation) {
						toExt.setVisibility(INVISIBLE);
					}
					@Override
					public void onAnimationRepeat(Animation animation) { }
					@Override
					public void onAnimationEnd(Animation animation) {
						synchronized (this) {
							if (mStopable) {
								mStopable = false;
								try {
									mBook.swapPosition(fromExt.getImage(), toExt.getImage());
								} catch (ImageIsEmptyException e) { }
							}
						}
					}
				};
				
				// Fix coordinates
				final int bitmapOffsetX = fromBitmap.getWidth()/2;
				final int bitmapOffsetY = fromBitmap.getHeight()/2;
				final int offsetX = getLeft();
				final int offsetY = getTop();
				final ViewGroup toVG = (ViewGroup) toExt.getParent();
				final int toX = toVG.getLeft() + offsetX + toExt.getLeft();
				final int toY = toVG.getTop() + offsetY + toExt.getTop();
				
				// Create animations
				Animation toAnimation;
				Animation fromAnimation = new TranslateAnimation(x + offsetX - bitmapOffsetX, toX, y + offsetY - bitmapOffsetY, toY);
				fromAnimation.setDuration(250);
				fromAnimation.setAnimationListener(al);
				
				// Create an animation set if dragged from another page
				if (fromExt.getPageDraggedFrom() != mBook.getPage()) {
					toAnimation = mPageBar.createAnimationToPageBar(fromExt.getPageDraggedFrom(), toX, toY, bitmapOffsetX, bitmapOffsetY, al);
				} else {
					int fromX = fromExt.getParentOffsetX() + offsetX + fromExt.getLeft();
					int fromY = fromExt.getParentOffsetY() + offsetY + fromExt.getTop();
					toAnimation = new TranslateAnimation(toX, fromX, toY, fromY);
					toAnimation.setDuration(250);
					toAnimation.setAnimationListener(al);
				}
				
				// Start animation
				mAnimationLayout.startAnimationInView(toBiv, toAnimation, al);
				mAnimationLayout.startAnimationInView(fromBiv, fromAnimation, al);
				
				return true;
			}
		} catch (NoViewFoundException e) { }
		
		return false;
	}

	@Override
	public void onDragIn(int x, int y) {
	}

	@Override
	public void onDragOut() {
	}
	
}
